package com.hegongda.okcmall.product.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hegongda.common.product.ProductStatusEnum;
import com.hegongda.common.to.SkuReductionTo;
import com.hegongda.common.to.SkuStockVo;
import com.hegongda.common.to.SpuBoundsTo;
import com.hegongda.common.to.es.Attrs;
import com.hegongda.common.to.es.SkuEsModel;
import com.hegongda.common.utils.R;
import com.hegongda.okcmall.product.entity.*;
import com.hegongda.okcmall.product.fegin.CouponService;
import com.hegongda.okcmall.product.fegin.SearchService;
import com.hegongda.okcmall.product.fegin.WareService;
import com.hegongda.okcmall.product.service.*;
import com.hegongda.okcmall.product.vo.Attr;
import com.hegongda.okcmall.product.vo.Images;
import com.hegongda.okcmall.product.vo.Skus;
import org.apache.commons.lang3.StringUtils;

import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hegongda.common.utils.PageUtils;
import com.hegongda.common.utils.Query;

import com.hegongda.okcmall.product.dao.SpuInfoDao;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SkuInfoService skuInfoService;

    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    private SkuImagesService skuImagesService;

    @Autowired
    private CouponService couponService;


    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private AttrService attrService;

    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Autowired
    private WareService wareService;

    @Autowired
    private SearchService searchService;


    @Override
    public void up(Long spuId) {

        List<SkuInfoEntity> skuInfoEntityList = skuInfoService.selectSkuBySpuId(spuId);
        List<Long> skuIds = skuInfoEntityList.stream().map(skuInfoEntity -> skuInfoEntity.getSkuId()).collect(Collectors.toList());

        // 设置属性
        List<ProductAttrValueEntity> attrValueEntities =
                productAttrValueService.list(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        List<Long> attrIds = attrValueEntities.stream().map(attrValueEntity -> attrValueEntity.getAttrId()).filter(id -> {
            AttrEntity byId = attrService.getById(id);
            return byId.getSearchType() == 1;
        }).collect(Collectors.toList());
        Set<Long> ids = new HashSet<>(attrIds); // 将list转化为set
        List<Attrs> attrsList = attrValueEntities.stream().filter(item -> ids.contains(item.getAttrId())).map(item -> {
            Attrs attrs = new Attrs();
            BeanUtils.copyProperties(item, attrs);
            return attrs;
        }).collect(Collectors.toList());

        // 远程调用仓库系统查询是否有库存 （避免单个sku循环发送远程请求，通过批量的方式进行查询）
        Map<Long, Boolean> map = null;
        try {
            List<SkuStockVo> skuStockVos =  wareService.hasStock(skuIds);
            map = skuStockVos.stream().collect(Collectors.toMap(SkuStockVo::getSkuId, SkuStockVo::getHasStock));
            // System.out.println(skuStockVos.get(0).getSkuId());
        } catch (Exception e){
            e.printStackTrace();
            System.out.println("远程调用不稳定");
        }

        Map<Long, Boolean> finalMap = map;
        List<SkuEsModel> collect = skuInfoEntityList.stream().map(skuInfoEntity -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            skuEsModel.setBrandId(skuInfoEntity.getBrandId());
            skuEsModel.setCatalogId(skuInfoEntity.getCatalogId());
            skuEsModel.setSaleCount(skuInfoEntity.getSaleCount() == null ? 0:skuInfoEntity.getSaleCount());
            skuEsModel.setSkuId(skuInfoEntity.getSkuId());
            skuEsModel.setSkuImg(skuInfoEntity.getSkuDefaultImg());

            skuEsModel.setSpuId(spuId);
            skuEsModel.setSkuTitle(skuInfoEntity.getSkuTitle());
            skuEsModel.setSkuPrice(skuInfoEntity.getPrice());
            skuEsModel.setHotScore(0L);  // 设置评分默认为0分

            // 设置是否有库存,当出现调用异常时返回null
            skuEsModel.setHasStock(finalMap == null ? true : finalMap.get(skuInfoEntity.getSkuId()));

            // 设置品牌名
            BrandEntity brandEntity = brandService.selectByBrandId(skuEsModel.getBrandId());
            skuEsModel.setBrandName(brandEntity.getName());
            skuEsModel.setBrandImg(brandEntity.getLogo());

            // 设置分类名
            CategoryEntity categoryEntity = categoryService.selectById(skuEsModel.getCatalogId());
            skuEsModel.setCatalogName(categoryEntity.getName());

            // 设置属性
            skuEsModel.setAttrs(attrsList);

            return skuEsModel;
        }).collect(Collectors.toList());

        //TODO 将collect发送给搜索服务进行上架
        R r = searchService.up(collect);
        if (r.getCode() != 0){
            // 上架失败
        } else {
            // 跟新上架
            SpuInfoEntity spuInfoEntity = baseMapper.selectById(spuId);
            spuInfoEntity.setPublishStatus(ProductStatusEnum.UP_SPU.getCode());
            baseMapper.updateById(spuInfoEntity);
        }

    }


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void saveSkuInfo(Long brandId, Long catalogId, Long id, List<Skus> skus) {
        for (Skus sku : skus) {
            // 保存sku的基本信息
            SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
            BeanUtils.copyProperties(sku, skuInfoEntity);
            skuInfoEntity.setBrandId(brandId);
            skuInfoEntity.setCatalogId(catalogId);
            skuInfoEntity.setSpuId(id);
            List<String> imgUrls = sku.getImages().stream()
                    .filter(image -> image.getDefaultImg() == 1)
                    .map(image -> image.getImgUrl())
                    .collect(Collectors.toList());
            if (imgUrls != null && imgUrls.size() > 0){
                skuInfoEntity.setSkuDefaultImg(imgUrls.get(0));
            }
            skuInfoService.save(skuInfoEntity);
            // 保存sku的attr
            List<Attr> attrs = sku.getAttr();
            skuSaleAttrValueService.saveSkuInfo(skuInfoEntity.getSkuId(), attrs);
            // 保存sku的images
            List<Images> images = sku.getImages();
            skuImagesService.saveSkuImage(skuInfoEntity.getSkuId(), images);
            // 远程保存满减信息以及满减打折信息
            SkuReductionTo skuReductionTo = new SkuReductionTo();
            BeanUtils.copyProperties(sku,skuReductionTo);
            skuReductionTo.setSkuId(skuInfoEntity.getSkuId());
            couponService.saveSkuReduction(skuReductionTo);
        }
    }

    @Override
    public PageUtils querySpuByCondition(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> queryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)){
            queryWrapper.and(obj -> obj.eq("id",key).or().like("spu_name",key));
        }
        String brandId = (String) params.get("brandId");
        if (StringUtils.isNotEmpty(brandId) && !brandId.equals("0")){
            queryWrapper.eq("brand_id", brandId);
        }
        String catelogId = (String) params.get("catelogId");
        if (StringUtils.isNotEmpty(catelogId) && !catelogId.equals("0")){
            queryWrapper.eq("catalog_id", catelogId);
        }
        String status = (String) params.get("status");
        if (StringUtils.isNotEmpty(status)){
            queryWrapper.eq("publish_status", status);
        }
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }


}